package com.zf.bm.common.core.base.service;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zf.bm.common.core.base.entity.BaseEntity;
import com.zf.bm.common.validator.BeanValidators;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Collection;
import java.util.List;

/**
 * Service基类
 */
@Slf4j
public abstract class BaseService<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> {

    public static final String TOKEN_TAG = "Token:";

    /**
     * 验证Bean实例对象
     */
    @Autowired
    protected Validator validator;

    @Override
    public boolean save(T entity) {
        if (!beanValidator(entity)) {
            return false;
        }
        return super.save(entity);
    }

    @Override
    public boolean saveOrUpdate(T entity) {
        if (!beanValidator(entity)) {
            return false;
        }
        return super.saveOrUpdate(entity);
    }

    @Override
    public boolean saveBatch(Collection<T> entityList, int batchSize) {
        for (T entity : entityList) {
            if (!beanValidator(entity)) {
                return false;
            }
        }
        return super.saveBatch(entityList, batchSize);
    }

    @Override
    public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
        for (T entity : entityList) {
            if (!beanValidator(entity)) {
                return false;
            }
        }
        return super.saveOrUpdateBatch(entityList, batchSize);
    }

    @Override
    public boolean updateById(T entity) {
        if (!beanValidator(entity)) {
            return false;
        }
        return super.updateById(entity);
    }

    @Override
    public boolean update(T entity, Wrapper<T> updateWrapper) {
        return super.update(entity, updateWrapper);
    }

    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        for (T entity : entityList) {
            if (!beanValidator(entity)) {
                return false;
            }
        }
        return super.updateBatchById(entityList, batchSize);
    }

    /**
     * 服务端参数有效性验证
     *
     * @param entity 验证的实体对象
     * @param groups 验证组
     * @return 验证成功：返回true；严重失败：将错误信息添加到 message 中
     */
    protected boolean beanValidator(T entity, Class<?>... groups) {
        try {
            BeanValidators.validateWithException(validator, entity, groups);
        } catch (ConstraintViolationException ex) {
            List<String> list = BeanValidators.extractPropertyAndMessageAsList(ex, ": ");
            StringBuilder message = new StringBuilder();
            for (String msg : list) {
                message.append(msg).append("\n");
            }
            entity.setErrors(message.toString());
            log.error("数据验证失败:{}", list);
            return false;
        }
        return true;
    }

    /**
     * 设备缓存头
     *
     * @param key 模块
     * @return 字符串
     */
    public static <T> String toTokenTag(T key) {
        return TOKEN_TAG + key;
    }
}
